package com.vx.ratingTool.match;

import java.util.ArrayList;
import java.util.List;

import com.vx.ratingTool.Player;

public class MatchFinder {
	private List<Player> playerPool;
	private Player searchingPlayer;
	private int searchRange;
	private List<Player> foundPlayers;
	private int searchRangeIncrement;

	public MatchFinder(List<Player> playerPool, Player searchingPlayer, int searchRangeBase, int searchRangeIncrement) {
		super();
		this.playerPool = playerPool;
		this.searchingPlayer = searchingPlayer;
		this.searchRange = searchRangeBase;
		this.searchRangeIncrement = searchRangeIncrement;
	}

	public Match findMatch() {
		Match newMatch;

		setFoundPlayers(new ArrayList<Player>());
		foundPlayers.add(searchingPlayer);
		// search for players with this search range, if not found increase it
		while (getFoundPlayers().size() < 10) {
			for (int i = 0; i < playerPool.size(); i++) {

				Player nextPlayer = playerPool.get(i);

				if (nextPlayer.getId() != searchingPlayer.getId() & !PlayerIsFoundAlready(foundPlayers, nextPlayer.getId())) {

					// checking if next player in the pool is in rating range
					if (nextPlayer.getRating() >= searchingPlayer.getRating() - searchRange
							& nextPlayer.getRating() <= searchingPlayer.getRating() + searchRange) {
						foundPlayers.add(nextPlayer);
						if (foundPlayers.size() == 10)
							break;
					}
				}
			}
			searchRange += searchRangeIncrement;
		}

		// create equal teams from found players
		int ratingDiff, ratingDiffBest;
		List<Player> currentList, bestList, teamA, teamB;

		currentList = new ArrayList<Player>(foundPlayers);
		ratingDiffBest = CalculateRatingDiff(currentList);
		bestList = new ArrayList<Player>(currentList);

		for (int i = 0; i < 5; i++) { // for each player in team 1
			for (int j = 5; j < 10; j++) {// swap with each player of team 2
				currentList = new ArrayList<Player>(foundPlayers);
				currentList.set(i, getFoundPlayers().get(j));
				currentList.set(j, getFoundPlayers().get(i));
				ratingDiff = CalculateRatingDiff(currentList); // calc diff
				if (ratingDiff < ratingDiffBest) {
					ratingDiffBest = ratingDiff;
					bestList = new ArrayList<Player>(currentList);
				}
			}
		}

		// create match
		teamA = new ArrayList<Player>();
		teamB = new ArrayList<Player>();

		for (int j = 0; j < 5; j++) {
			teamA.add(bestList.get(j));
			teamB.add(bestList.get(5 + j));
		}
		newMatch = new Match(teamA, teamB);
		return newMatch;
	}

	private void setFoundPlayers(ArrayList<Player> arrayList) {
		this.foundPlayers = arrayList;

	}

	private int CalculateRatingDiff(List<Player> currentList) {
		int ratingA, ratingB;
		ratingA = 0;
		for (int j = 0; j < 5; j++) {
			ratingA += currentList.get(j).getRating();
		}
		ratingB = 0;
		for (int j = 5; j < 10; j++) {
			ratingB += currentList.get(j).getRating();
		}
		return Math.abs(ratingA - ratingB);
	}

	private boolean PlayerIsFoundAlready(List<Player> players, int id) {
		for (int i = 0; i < players.size(); i++) {
			if (players.get(i).getId() == id)
				return true;
		}
		return false;
	}

	public List<Player> getFoundPlayers() {
		List<Player> toaddList = new ArrayList();
		for (int i = 0; i < foundPlayers.size(); i++) {
			toaddList.add(new Player(foundPlayers.get(i)));
		}
		return toaddList;
	}

}
